/**************************************************************************************
*
*	Copyright (C) 2010 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	GraphicsResourceManager.cpp
*
*	Comments	-	See GraphicsResourceManager.h
*
**************************************************************************************/

#ifdef __PSX_WINDOWS_WINDOW

#include "../Include/GraphicsResourceManager.h"
#include "../Include/GraphicsTypes.h"
#include "../Include/ResourceManager.h"

namespace Pulse
{

	GraphicsResourceManager::GraphicsResourceManager( void )
	{

	}

	GraphicsResourceManager::~GraphicsResourceManager( void )
	{

	}

	EErrorCode::Type GraphicsResourceManager::Initialize( void )
	{

		m_textures.Create( 16 );
		m_vertexDeclarations.Create( 5 );
		m_vertexBuffers.Create( 16 );

		ResourceManager *pResMan = ResourceManager::GetInstance();
		pResMan->RegisterResourcePool( &m_textures, ResourceRegisterCode( EResourceType::VIDEO, EVideoResourceType::TEXTURE ) );
		pResMan->RegisterResourcePool( &m_vertexDeclarations, ResourceRegisterCode( EResourceType::VIDEO, EVideoResourceType::VERTEX_DECLARATION ) );
		pResMan->RegisterResourcePool( &m_vertexBuffers, ResourceRegisterCode( EResourceType::VIDEO, EVideoResourceType::VERTEX_BUFFER ) );

		return EErrorCode::NONE;
	}

	void GraphicsResourceManager::Cleanup( void )
	{
		m_vertexBuffers.DestroyAllResources();
		m_vertexDeclarations.DestroyAllResources();
		m_textures.DestroyAllResources();

		ResourceManager *pResMan = ResourceManager::GetInstance();
		pResMan->UnregisterResourcePool( ResourceRegisterCode( EResourceType::VIDEO, EVideoResourceType::TEXTURE ) );
		pResMan->UnregisterResourcePool( ResourceRegisterCode( EResourceType::VIDEO, EVideoResourceType::VERTEX_DECLARATION ) );
		pResMan->UnregisterResourcePool( ResourceRegisterCode( EResourceType::VIDEO, EVideoResourceType::VERTEX_BUFFER ) );
	}

	Texture * GraphicsResourceManager::CreateTexture( const CHAR *pName, UINT width, UINT height, ETextureType::Type type, 
		ETextureUsage::Type usage, ETextureFormat::Type format, UINT depth )
	{
		Texture *pTexture = m_textures.CreateResource( pName );

		if ( !pTexture )
			return PSX_NULL;

		pTexture->Create( width, height, type, usage, format, depth );

		return pTexture;
	}

	Texture * GraphicsResourceManager::CreateTextureFromFile( const CHAR *pFilename, ETextureType::Type type, 
		ETextureUsage::Type usage, ETextureFormat::Type format )
	{
		Texture *pTexture = m_textures.CreateResource( pFilename );

		if ( !pTexture )
			return PSX_NULL;

		pTexture->CreateFromFile( pFilename, type, usage, format );

		return pTexture;
	}

	//VertexDeclaration * GraphicsResourceManager::CreateVertexDeclaration( const CHAR *pName, VertexElement *pElems, SIZE_T size )
	//{
	//	VertexDeclaration *pDecl = m_vertexDeclarations.CreateResource( pName );

	//	if ( !pDecl )
	//		return PSX_NULL;

	//	pDecl->AddVertexElement( pElems, size );
	//	return pDecl;
	//}

	VertexDeclaration * GraphicsResourceManager::CreateVertexDecleration( const CHAR *pName )
	{

	}

	VertexBuffer * GraphicsResourceManager::CreateVertexBuffer( const CHAR *pName, const VertexBufferDescription *pDesc )
	{
		VertexBuffer *pBuffer = m_vertexBuffers.CreateResource( pName );

		if ( !pBuffer )
			return PSX_NULL;

		pBuffer->SetBufferDecription( pDesc );
		return pBuffer;
	}

	void GraphicsResourceManager::CreateVertexDeclarations( void )
	{
		VertexElement elem1P1D[] = {
			{ 0, 0, EVertexElementUsage::POSITION, 0 },
			{ 0, 12, EVertexElementUsage::COLOR, 0 },
		};

		CreateVertexDeclaration( PSX_String("1P1D"), elem1P1D, sizeof(elem1P1D) / sizeof( *elem1P1D) );
	}

	void GraphicsResourceManager::AddShaderConstantSemantic( ShaderConstantSemantic *pSemantic )
	{
		if ( m_semanticMap.Find( pSemantic->name ) != m_semanticMap.IteratorEnd() )
		{
			PSX_PushWarning( "Shader constant semantic \"%s\" already registerd.", pSemantic->name );
			return;
		}

		m_semanticMap[ pSemantic->name ] = pSemantic;
	}

	ShaderConstantSemantic * GraphicsResourceManager::GetShaderConstantSemantic( const CHAR *pName )
	{
		if ( m_semanticMap.Find( pName ) == m_semanticMap.IteratorEnd() )
		{
			PSX_PushError( "Semantic %s does not exist.", pName );
			return PSX_NULL;
		}

		return m_semanticMap[ pName ];
	}

	//void GraphicsResourceManager::AddShaderConstantType( ShaderConstantType *pDataType )
	//{
	//	if ( m_constantTypeMap.Find( pDataType->name ) != m_constantTypeMap.IteratorEnd() )
	//	{
	//		PSX_PushWarning( "Shader constant type \"%s\" already registerd.", pDataType->name );
	//		return;
	//	}

	//	m_constantTypeMap[ pDataType->name ] = pDataType;
	//}

	//ShaderConstantType * GraphicsResourceManager::GetShaderConstantType( const CHAR *pName )
	//{
	//	if ( m_constantTypeMap.Find( pName ) == m_constantTypeMap.IteratorEnd() )
	//	{
	//		PSX_PushError( "Shader constant type \"%s\" does not exist.", pName );
	//		return PSX_NULL;
	//	}

	//	return m_constantTypeMap[ pName ];
	//}

}

#endif __PSX_WINDOWS_WINDOW
